#ifndef PW_PBL_MACRO_HPP
#define PW_PBL_MACRO_HPP

#define _pw_pbl_PARENS ()
#define _pw_pbl_LPAREN (
#define _pw_pbl_RPAREN )
#define _pw_pbl_INTERFACE_CONCAT(a, b) a##b

// Rescan macro tokens 256 times
#define _pw_pbl_EXPAND(...) _pw_pbl_EXPAND1(_pw_pbl_EXPAND1(_pw_pbl_EXPAND1(_pw_pbl_EXPAND1(__VA_ARGS__))))
#define _pw_pbl_EXPAND1(...) _pw_pbl_EXPAND2(_pw_pbl_EXPAND2(_pw_pbl_EXPAND2(_pw_pbl_EXPAND2(__VA_ARGS__))))
#define _pw_pbl_EXPAND2(...) _pw_pbl_EXPAND3(_pw_pbl_EXPAND3(_pw_pbl_EXPAND3(_pw_pbl_EXPAND3(__VA_ARGS__))))
#define _pw_pbl_EXPAND3(...) _pw_pbl_EXPAND4(_pw_pbl_EXPAND4(_pw_pbl_EXPAND4(_pw_pbl_EXPAND4(__VA_ARGS__))))
#define _pw_pbl_EXPAND4(...) __VA_ARGS__

#define _pw_pbl_FOR_EACH_HELPER(macro, sep, a1, ...) macro(a1) __VA_OPT__(_pw_pbl_EXPAND4 sep) __VA_OPT__(_pw_pbl_FOR_EACH_AGAIN _pw_pbl_PARENS(macro, sep, __VA_ARGS__))
#define _pw_pbl_FOR_EACH_AGAIN() _pw_pbl_FOR_EACH_HELPER

/// 迭代宏，将指定宏应用到所有列表项
/// @param macro 宏或非宏均可，转换后为macro(item)
/// @param sep 分隔符，需要()包裹
/// @sample PW_PBL_FOR_EACH(int8, (;), 1, 2, 3, 4) 转换为 int8(1); int8(2); int8(3); int8(4)
/// 如果#define int8(n) (n+1) 则转换结果为 (1+1); (2+1); (3+1); (4+1)
#define PW_PBL_FOR_EACH(macro, sep, ...) __VA_OPT__(_pw_pbl_EXPAND(_pw_pbl_FOR_EACH_HELPER(macro, sep, __VA_ARGS__)))

#endif // PW_PBL_MACRO_HPP
